#region Using Statements
using System;
using System.IO;
using System.Xml;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Runtime.Remoting;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion

namespace SkyBurner
{
    public class SkyBurnerBonusManager : SkyBurnerWorldObject
    {
        private enum BonusType
        {
            Health,
            Rocket,
            Shield
        }

        private class BonusItem : BaseDrawableObject
        {
            private Vector3 m_vPosition;
            private MOODModel m_bonusModel;
            private float m_fSpinIncrement;
            private BonusType m_bonusType;

            public BoundingBoxEx BoundingBox
            {
                get { return m_bonusModel.BoundingBox; }
            }

            public BonusType Type
            {
                get { return m_bonusType; }
            }

            public BonusItem(BaseGame baseGame, Vector3 pPosition, MOODModel pBonusModel, BonusType pBonusType) :
                base(baseGame)
            {
                m_vPosition = pPosition;
                m_bonusModel = pBonusModel;
                m_fSpinIncrement = 0.0f;
                m_bonusType = pBonusType;
            }

            public override void Update(GameTime gameTime, Camera pActiveCamera)
            {
                base.Update(gameTime, pActiveCamera);

                m_bonusModel.WorldMatrix = Matrix.CreateRotationY(m_fSpinIncrement) * Matrix.CreateTranslation(m_vPosition);
                m_bonusModel.ViewMatrix = Matrix.CreateLookAt(pActiveCamera.Position, pActiveCamera.LookAt, pActiveCamera.Up);
                m_bonusModel.ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(pActiveCamera.FOV, pActiveCamera.AspectRatio, pActiveCamera.NearPlane, pActiveCamera.FarPlane);
                m_bonusModel.Update(gameTime, pActiveCamera);

                m_fSpinIncrement += 0.04f;
            }

            public override void Draw(GameTime gameTime, Camera pActiveCamera)
            {
                base.Draw(gameTime, pActiveCamera);
                m_bonusModel.Draw(gameTime, pActiveCamera);
            }
        }

        private MOODModel m_moodHealth;
        private MOODModel m_moodRocket;
        private MOODModel m_moodShield;
        private BonusItem m_activeBonusItem;
        private float m_fLastBonusSpawn;
        private Random m_randomGen;

        public SkyBurnerBonusManager(BaseGame game, SkyBurnerWorld pSkyBurnerWorld)
            : base(game, pSkyBurnerWorld)
        {
            // initialize models...
            m_moodHealth = new MOODModel(game, "Data\\Models\\bonus_health.mood");
            m_moodRocket = new MOODModel(game, "Data\\Models\\bonus_rocket.mood");
            m_moodShield = new MOODModel(game, "Data\\Models\\bonus_shield.mood");
            
            // initialize our toys
            m_randomGen = new Random();
            m_activeBonusItem = null;
            m_fLastBonusSpawn = 0.0f;
        }

        public override void Update(GameTime gameTime, Camera pActiveCamera)
        {
            base.Update(gameTime, pActiveCamera);

            if (m_fLastBonusSpawn == 0.0f)
                m_fLastBonusSpawn = (float)gameTime.TotalGameTime.TotalMilliseconds;
            else
            {
                if ((gameTime.TotalGameTime.TotalMilliseconds - m_fLastBonusSpawn) >= 10000.0f)
                {
                    BonusType bonusType = (BonusType)(m_randomGen.Next(0, 100) % 3);

                    // spawn bonus item...
                    Vector3 pBonusPosition = pActiveCamera.Position;
                    pBonusPosition.Z += 200.0f;

                    switch (bonusType)
                    {
                        case BonusType.Health:
                            {
                                m_activeBonusItem = new BonusItem(m_Game, pBonusPosition, m_moodHealth, bonusType);
                                break;
                            }

                        case BonusType.Rocket:
                            {
                                m_activeBonusItem = new BonusItem(m_Game, pBonusPosition, m_moodRocket, bonusType);
                                break;
                            }

                        case BonusType.Shield:
                            {
                                m_activeBonusItem = new BonusItem(m_Game, pBonusPosition, m_moodShield, bonusType);
                                break;
                            }
                    }
                            

                    m_fLastBonusSpawn = (float)gameTime.TotalGameTime.TotalMilliseconds;
                }
            }    
 
            // check for collision with player...
            if (m_activeBonusItem != null)
            {
                m_activeBonusItem.Update(gameTime, pActiveCamera);

                if (m_skyBurnerWorld.Player.BoundingBox.Intersect(m_activeBonusItem.BoundingBox))
                {
                    switch (m_activeBonusItem.Type)
                    {
                        case BonusType.Health:
                            {
                                m_Game.SoundManager.PlaySound("bonus_health");
                                SkyBurnerGlobal.IncrementEnergy(10);
                                break;
                            }

                        case BonusType.Rocket:
                            {
                                m_Game.SoundManager.PlaySound("bonus_rocket");
                                SkyBurnerGlobal.IncrementRocket();
                                break;
                            }

                        case BonusType.Shield:
                            {
                                m_Game.SoundManager.PlaySound("bonus_rocket");
                                SkyBurnerGlobal.IncrementShield(25);
                                break;
                            }
                    }

                    m_activeBonusItem = null;
                }
            }
        }

        public override void Draw(GameTime gameTime, Camera pActiveCamera)
        {
            base.Draw(gameTime, pActiveCamera);

            if ( m_activeBonusItem != null)
                m_activeBonusItem.Draw(gameTime, pActiveCamera);
        }
    }
}
